package com.leyou.item.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.pojo.PageResult;
import com.leyou.common.utils.BeanHelper;
import com.leyou.item.dto.SeckillGoodsDTO;
import com.leyou.item.dto.SeckillParameter;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.mapper.SeckillMapper;
import com.leyou.item.pojo.SeckillGoods;
import com.leyou.item.pojo.Sku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SeckillService extends ServiceImpl<SeckillMapper, SeckillGoods> {

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private SeckillMapper seckillMapper;

    public void addSeckillGoods(List<SeckillParameter> seckillList) {
        try {
            List<Long> ids = seckillList.stream().map(SeckillParameter::getId).collect(Collectors.toList());
            List<Sku> skuList = goodsService.findSkusByIds(ids);

            List<SeckillGoods> seckillGoodsList = new ArrayList<>();

            skuList.forEach(sku -> {
                seckillList.forEach(seckill -> {
                    if (seckill.getId().equals(sku.getId())) {
                        SeckillGoods seckillGoods = BeanHelper.copyProperties(sku, SeckillGoods.class);

                        seckillGoods.setId(null);
                        seckillGoods.setSkuId(seckill.getId());
                        seckillGoods.setStartTime(seckill.getStartTime());
                        seckillGoods.setEndTime(seckill.getEndTime());
                        seckillGoods.setEnable(false);
                        seckillGoods.setSkillStock(seckill.getCount());
                        seckillGoods.setDiscount(seckill.getDiscount());

                        seckillGoodsList.add(seckillGoods);
                    }
                });
            });

            saveBatch(seckillGoodsList);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    public PageResult<SeckillGoodsDTO> myBrandPage(Integer page, Integer rows, String key, Boolean saleable) {
        try {
            //设置分页信息
            IPage<SeckillGoods> iPage = new Page<>(page, rows);
            //构建封装条件和排序的对象
            QueryWrapper<SeckillGoods> wrapper = Wrappers.query();
            //先对key判空
            if (StringUtils.isNotBlank(key)) {
                wrapper.eq("title", key);
            }
            if (saleable != null) {
                wrapper.eq("enable", saleable);
            }

            //分页条件查询
            iPage = seckillMapper.selectPage(iPage, wrapper);

            List<SeckillGoods> seckillGoodsList = iPage.getRecords();

            List<SeckillGoodsDTO> seckillGoodsDTOList = BeanHelper.copyWithCollection(seckillGoodsList, SeckillGoodsDTO.class);

            handlerSkuAndBrandNmae(seckillGoodsDTOList);
            //封装自定义的分页对象
            PageResult<SeckillGoodsDTO> pageResult = new PageResult<>(
                    iPage.getTotal(),
                    iPage.getPages(),
                    seckillGoodsDTOList
            );
            return pageResult;
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }


    }

    private void handlerSkuAndBrandNmae(List<SeckillGoodsDTO> seckillGoodsDTOList) {

        seckillGoodsDTOList.forEach(seckillGoodsDTO -> {
            Sku sku = goodsService.findSkuById(seckillGoodsDTO.getSkuId());
            seckillGoodsDTO.setSku(sku);

            SpuDTO spuDTO = goodsService.findSpuById(sku.getSpuId());
            seckillGoodsDTO.setSpuName(spuDTO.getName());
            seckillGoodsDTO.setBrandName(spuDTO.getBrandName());

            seckillGoodsDTO.setSkillPrice(sku.getPrice() * seckillGoodsDTO.getDiscount());
        });

    }

    public void updateSaleable(Long id, Boolean saleable) {
        try {
            //封装修改条件对象，其中对象中的id必须赋值
            SeckillGoods goods = new SeckillGoods();
            goods.setId(id);
            goods.setEnable(saleable);
            seckillMapper.updateById(goods);

            //通过feign调用search微服务和page微服务，同步确保数据同步
            //通过MQ异步去维护search微服务和page微服务的数据同步
            //根据当前是上架或者下架操作来指定routingKey
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }


    public PageResult<SeckillGoodsDTO> findSeckillGoodsDTO(Integer page) {

        try {
            IPage<SeckillGoods> iPage = new Page<>(page, 12);
            LambdaQueryWrapper<SeckillGoods> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(SeckillGoods::getEnable, true);
            IPage<SeckillGoods> seckillGoodsIPage = page(iPage, wrapper);

            List<SeckillGoodsDTO> seckillGoodsDTOList = BeanHelper.copyWithCollection(seckillGoodsIPage.getRecords(), SeckillGoodsDTO.class);

            handlerSkuAndBrandNmae(seckillGoodsDTOList);

            PageResult<SeckillGoodsDTO> pageResult = new PageResult<>(
                    seckillGoodsIPage.getTotal(),
                    seckillGoodsIPage.getPages(),
                    seckillGoodsDTOList);
            return pageResult;
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
    }

    public SeckillGoodsDTO findSeckSkuById(Long id) {
        try {
            SeckillGoods seckillGoods = seckillMapper.selectById(id);
            SeckillGoodsDTO seckillGoodsDTO = BeanHelper.copyProperties(seckillGoods, SeckillGoodsDTO.class);

            Sku sku = goodsService.findSkuById(seckillGoods.getSkuId());
            SpuDTO spuDTO = goodsService.findSpuById(sku.getSpuId());

            seckillGoodsDTO.setSkillPrice(sku.getPrice() * seckillGoods.getDiscount());
            seckillGoodsDTO.setSku(sku);
            seckillGoodsDTO.setBrandName(spuDTO.getBrandName());
            seckillGoodsDTO.setSpuName(spuDTO.getName());
            return seckillGoodsDTO;
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
    }

    public void minusSeckillStock(Long skuId) {
        try {
            QueryWrapper<SeckillGoods> query = Wrappers.query();
            query.eq("sku_id", skuId);
            SeckillGoods seckillGoods = seckillMapper.selectOne(query);
            seckillGoods.setSkillStock(seckillGoods.getSkillStock() - 1);
            seckillMapper.updateById(seckillGoods);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    /**
     * 查询秒杀商品列表
     */
    public List<SeckillGoods> findAllSeckill() {
        return seckillMapper.selectList(null);
    }
}
